package com.lqian.demo03.pug;

/**
 * 使用线程同步完成账户取钱的模拟操作代码，保证线程安全；具体要求如下：（7）
 * 1)定义账户Account类，可以取款、查看余额
 * 2)定义取款线程AccountRunable，实现取款
 * 3)定义测试类，模拟两个线程同时取款
 */
/*线程同步机制解决线程安全问题*/
public class Demo04 {

    public static void main(String [] agrs) {
        //定义线程内部类
        class AccountRunable extends Thread{
            private Account act;//账户对象

            public AccountRunable(Account act) {
                super();
                this.act = act;
            }

            public void run() {
                //取款5000
                double money=5000;
                act.getruch(money);
                System.out.println("线程"+Thread.currentThread()+"取款"+money+"对账户取款成功!余额还有"+act.getBalance());
            }
        }
        //创建卡
        Account a1=new Account("action--1",10000);
        //模拟两个线程
        Thread t1=new AccountRunable(a1);
        Thread t2=new AccountRunable(a1);
        t1.setName("t1");
        t2.setName("t2");
        //启动
        t1.start();
        t2.start();
    }
}
//定义账户类
class Account{
    private String  id;//卡号
    private  double balance;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public Account(String id, double balance) {
        super();
        this.id = id;
        this.balance = balance;
    }

    //取款方法
    public void getruch(double money) {
        //这里的代码必须使用线程同步机制
        synchronized(this){
            //synchronized后面括号写的是线程共享的资源
            double before =this.getBalance();
            double after=before-money;
            try {
                Thread.sleep(1000*2);
            } catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }//等待时间
            this.setBalance(after);
        }
    }
}

